package api

import (
	"batbat-backend/app/model"
	"batbat-backend/app/service"
	"batbat-backend/library/jwt"
	"batbat-backend/library/response"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/util/gconv"
)

// User 用户API接口
var User = userApi{}

type userApi struct{}

// Register
// @summary	用户注册(需要加密)
// @tags 	用户
// @accept	mpfd
// @param	phoneNumber formData string true "电话号码"
// @param	password formData string true "密码, 长度在6到16之间"
// @param	inviteCode formData string true "内测码"
// @produce	json
// @success	200 {object} response.JsonResponse{data=model.UserApiRegisterResp}
// @router /user [POST]
func (u *userApi) Register(r *ghttp.Request) {
	var (
		req  *model.UserApiRegisterReq
		resp *model.UserApiRegisterResp
	)
	err := service.Rsa.Decrypt(r, &req)
	if err != nil {
		response.Error(r, err)
	}
	user, err := service.User.Register(r.Context(), req.PhoneNumber, req.Password, req.InviteCode)
	if err != nil {
		response.Error(r, err)
	}
	err = gconv.Struct(user, &resp)
	if err != nil {
		g.Log().Ctx(r.Context()).Errorf("将用户对象转为model.UserApiRegisterResp失败: %v", err)
		response.Error(r, gerror.New("注册失败"))
	}
	response.Success(r, resp)
}

// GetInformation
// @summary	获取用户个人资料
// @tags 	用户
// @param 	Authorization header string true "token"
// @produce	json
// @success	200 {object} response.JsonResponse{data=model.UserContext}
// @router /user [GET]
func (u *userApi) GetInformation(r *ghttp.Request) {
	var uContext *model.UserContext
	err := r.GetCtxVar(model.UserContextKey).Scan(&uContext)
	if err != nil {
		response.Error(r, gerror.New("获取用户个人资料失败"))
	}
	user, err := service.User.GetInformation(r.Context(), uContext.Id)
	if err != nil {
		response.Error(r, err)
	}
	err = gconv.Scan(user, &uContext)
	if err != nil {
		g.Log().Ctx(r.Context()).Errorf("将用户对象转为用户上下文对象失败: %v", err)
		response.Error(r, gerror.New("获取用户个人资料失败"))
	}
	response.Success(r, uContext)
}

// ModifyInformation
// @summary 修改用户个人资料
// @tags 	用户
// @accept	mpfd
// @param 	Authorization header string true "token"
// @param	username formData string true "用户名"
// @param	avatar formData string true "头像地址"
// @param	birthday formData string false "出生日期"
// @param	gender formData int true "性别 0-保密 1-男 2-女"
// @param	introduction formData string true "个人介绍"
// @produce	json
// @success	200 {object} response.JsonResponse{data=model.UserApiModifyInformationResp}
// @router /user [PUT]
func (u *userApi) ModifyInformation(r *ghttp.Request) {
	// 解决birthday传入参数为空串的时候不为nil的问题
	if !r.GetVar("birthday").IsNil() && r.GetVar("birthday").String() == "" {
		r.SetForm("birthday", nil)
	}
	var req *model.UserApiModifyInformationReq
	err := r.ParseForm(&req)
	if err != nil {
		response.Error(r, err)
	}
	user, err := service.User.ModifyInformation(r.Context(), req)
	if err != nil {
		response.Error(r, err)
	}
	token, err := jwt.Generate(user)
	if err != nil {
		g.Log().Ctx(r.Context()).Errorf("生成jwt失败: %v", err)
		response.Error(r, gerror.New("修改用户个人资料失败"))
	}
	response.Success(r, &model.UserApiModifyInformationResp{
		User:  user,
		Token: token,
	})
}

// GetUser
// @summary 获取用户个人中心信息
// @tags 	用户
// @param 	Authorization header string true "token"
// @param	id path int true "待查询的用户id"
// @produce	json
// @success	200 {object} response.JsonResponse{data=model.UserApiGetUserResp}
// @router /user/{id} [GET]
func (u *userApi) GetUser(r *ghttp.Request) {
	id := r.GetUint("id")
	if id == 0 {
		response.Error(r, gerror.New("路径参数有误, 请校验路径参数`id`"))
	}
	resp, err := service.User.GetUser(r.Context(), id)
	if err != nil {
		response.Error(r, err)
	}
	response.Success(r, resp)
}

// GetUserFavor
// @summary 获取用户个人收藏的游戏
// @tags 	用户
// @param	id path int true "待查询的用户id"
// @produce	json
// @success	200 {object} response.JsonResponse{data=model.UserApiGetUserFavorResp}
// @router /user/{id}/favor [GET]
func (u *userApi) GetUserFavor(r *ghttp.Request) {
	id := r.GetUint("id")
	if id == 0 {
		response.Error(r, gerror.New("路径参数有误, 请校验路径参数`id`"))
	}
	resp, err := service.User.GetUserFavor(r.Context(), id)
	if err != nil {
		response.Error(r, err)
	}
	response.Success(r, resp)
}

// Reviews
// @summary 获取用户个人作出的评论
// @tags 	用户
// @param	id path int true "待查询的用户id"
// @param	pn query int false "页码, 默认为1"
// @param	limit query int false "页面大小, 取之范围为5到10, 默认为10"
// @produce	json
// @success	200 {object} response.JsonResponse{data=model.UserApiReviewsResp}
// @router /user/{id}/review [GET]
func (u *userApi) Reviews(r *ghttp.Request) {
	var req *model.UserApiReviewsReq
	err := r.Parse(&req)
	if err != nil {
		response.Error(r, err)
	}
	resp, err := service.User.Reviews(r.Context(), req.Id, req.Pn, req.Limit)
	if err != nil {
		response.Error(r, err)
	}
	response.Success(r, resp)
}
